const Router = require('koa-router')
const axios = require('axios')
// 跟node中 fs 一模一样，并且扩展了
// memory-fs 不把文件写入磁盘上面，而是写在内存中
const MemoryFS = require('memory-fs')
const webpack = require('webpack')
const path = require('path')
const VueServerRenderer = require('vue-server-renderer')
const serverRender = require('./server-render')
const fs = require('fs')
const serverConfig = require('../../build/webpack.config.server')
// require 和 import
// import 是经过babel 编译的
// require 是不经过 babel 的 ，require 是可以直接运行的 不需要编译

const serverCompiler = webpack(serverConfig)
const mfs = new MemoryFS()
// 输出目录是在内存fs中
serverCompiler.outputFileSystem = mfs

let bundle
// 每次改文件 都可以拿到新文件
serverCompiler.watch({}, (err, stats) => {
  if (err) throw err
  //TODO
  stats = stats.toJson()
  stats.errors.forEach(err => console.log(err))
  stats.warnings.forEach(warn => console.warn(err))

  // 读取生成的bundle文件
  // path.join 就是把多个字符串连接在一起组成一个路径
  const bundlePath = path.join(
    serverConfig.output.path,
    // 这是个默认文件名，也可以定制
    'vue-ssr-server-bundle.json'
  )

  // 每次有文件变化 都拿到新的打包的东西
  bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
  console.log('new bundle generated')
})

const handleSSR = async(ctx) => {
  // 如果 bundle 不存在
  if (!bundle) {
    ctx.body = '你等一会儿，别着急.......'
    return
  }

  const clientManifestResp = await axios.get(
    'http://centos-49-92:8000/public/vue-ssr-client-manifest.json'
  )

  const clientManifest = clientManifestResp.data

  // 读取template
  const template = fs.readFileSync(
    path.join(__dirname, '../server.template.ejs'),
    'utf-8'
  )

  //生成一个帮我们调用render的桉树
  const renderer = VueServerRenderer
    .createBundleRenderer(bundle, {
      inject: false,
      clientManifest
    })

  await serverRender(ctx, renderer, template)
}

const router = new Router()
//所有路径都经过
router.get('*', handleSSR)

module.exports = router
